import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:async';
import 'dart:convert';

import 'package:netcat/server.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'netcat',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // TRY THIS: Try running your application with "flutter run". You'll see
        // the application has a purple toolbar. Then, without quitting the app,
        // try changing the seedColor in the colorScheme below to Colors.green
        // and then invoke "hot reload" (save your changes or press the "hot
        // reload" button in a Flutter-supported IDE, or press "r" if you used
        // the command line to start the app).
        //
        // Notice that the counter didn't reset back to zero; the application
        // state is not lost during the reload. To reset the state, use hot
        // restart instead.
        //
        // This works for code too, not just values: Most code changes can be
        // tested with just a hot reload.
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: const MyHomePage(title: 'Netcat'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _port = TextEditingController(text:'9000');
  final _host = TextEditingController(text:'192.168.240.1');
  final _message = TextEditingController();
  final _data = TextEditingController();
  final _scroller = ScrollController();
  late Socket client;
  bool connected = false;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    
    _data.addListener(() {
      scrollToEnd();
    });
  }

  void scrollToEnd() {
    if(_scroller.hasClients) {
      _scroller.animateTo(
      _scroller.position.maxScrollExtent,
      curve: Curves.easeOut,
      duration: const Duration(milliseconds: 300),
    );
    }
  }

  Future<void> _connect() async {
      var host = _host.text;
      int port = int.parse(_port.text);
      print('connect $host : $port\n');
      if (mounted){
        //setState(() {
        _data.text = 'server $host : $port\n';
        //});
      }
      try {
        client = await Socket.connect(host, port);
      }
      catch(e){
        if (mounted){
          //setState(() {
          _data.text = 'connect error: $e\n';
          //});
        }
      }
      
      
      if (mounted){
        _data.text = 'connected $host : $port\n';
      }
      setState(() {
        connected = true;
      });
      //client.add(utf8.encode('Hello, Server!\n'));

      // 监听服务器的响应
      client.listen(
        (data) {
          var message = utf8.decode(data);
          print('Received message from server: $message');
          
          if(mounted){
            //setState(() {
            _data.text ='${_data.text}$message';
            //});
          }
        },
        onDone: () {
          print('Server disconnected');
          client.destroy(); // 关闭客户端连接
          
          if(mounted){
            _data.text = '${_data.text}Server disconnected';
            setState(() {
              connected = false;
            });
          }
        },
        onError: (error) {
          print('Error: $error');
          client.destroy(); // 关闭客户端连接
          
          if(mounted){
            _data.text = 'Error: $error';
            setState(() {
              connected = false;
            });
          }
        },
      );
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    
    return Scaffold(
      appBar: AppBar(
        // TRY THIS: Try changing the color here to a specific color (to
        // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
        // change color while the other colors stay the same.
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          //
          // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
          // action in the IDE, or press "p" in the console), to see the
          // wireframe for each widget.
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            (!connected)?const Text('服务器IP和端口:'):const Text('发送信息'),
            if(!connected) TextField(
              controller: _host,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: '服务器IP',
              ),
            ),
            if(!connected) TextField(
              controller: _port,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: '端口',
              ),
            ),
            if(!connected) TextButton(
              onPressed: (){
                _connect();
              }, 
              child: Text("连接"),
            ),
            if(connected) TextField(
              controller: _message,
              maxLines: null, // 允许无限行
              keyboardType: TextInputType.multiline,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: '此处输入信息',
              ),
            ),
            if(connected) TextButton(
              onPressed: (){
                client.add(utf8.encode('${_message.text}\n'));
                _message.text='';
              }, 
              child: Text('发送'),
            ),
            TextField(
              controller: _data,
              scrollController: _scroller,
              readOnly: true,
              maxLines: 8,
              decoration: InputDecoration(
                border: UnderlineInputBorder(),
                hintText: '此处显示输出信息',
              ),
            ),
            TextButton(
              onPressed: (){
                Navigator.push<void>(context, MaterialPageRoute<void>(builder: (context)=>ServerMode()));
              }, 
              child: Text('服务器模式'),
            ),
          ],
        ),
      ),
    );
  }
}
